/*
    Android Asynchronous Http Client
    Copyright (c) 2013 JIXIAOLONG <MicroJixl@gmail.com>

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
 */

package com.jxl.netframe;
/** 
 * @author JiXL
 * @time 2013-6-6 上午10:55:13
 */
import android.os.Handler;
import android.os.Looper;
import android.os.Message;

public abstract class AsyncHttpResponseHandler<T> implements ProcessListener{
	protected static final int SUCCESS_MESSAGE = 0;
	protected static final int FAILURE_MESSAGE = 1;
	protected static final int CANCEL_MESSAGE = 2;
	protected static final int RETRY_MESSAGE = 3;
	protected static final int IOUP_MESSAGE = 4;
	protected static final int IODWON_MESSAGE = 5;
	private static final int LIMIT_TIME = 0;
	

	private Handler handler;

	/**
	 * Creates a new AsyncHttpResponseHandler
	 */
	public AsyncHttpResponseHandler() {
		// Set up a handler to post events back to the correct thread if possible
		if(Looper.myLooper() != null) {
			handler = new Handler(){
				private long lastTime = 0;
				@SuppressWarnings("unchecked")
				@Override
				public void handleMessage(Message msg){
					Object[] objs = null;
					if(msg.what != CANCEL_MESSAGE)
						objs = (Object[])msg.obj;
					switch (msg.what) {
					case SUCCESS_MESSAGE:
						onFinished((RequestParameter)objs[0],(T)objs[1]);
						onCompleted((RequestParameter)objs[0]);
						break;
					case FAILURE_MESSAGE:
						onFailed((RequestParameter)objs[0], (Exception)objs[1]);
						onCompleted((RequestParameter)objs[0]);
						break;
					case CANCEL_MESSAGE:
						onCanceled((RequestParameter)msg.obj);
						onCompleted((RequestParameter)msg.obj);
						break;
					case RETRY_MESSAGE:
						onRetry((RequestParameter)objs[0], (Integer)objs[1], (Exception)objs[2]);
						break;
					case IOUP_MESSAGE:
						long time = System.currentTimeMillis();
						if((time - lastTime)< LIMIT_TIME){
							//may UI update too fast.
							return;
						}
						lastTime = time;
						onUpBufferd((RequestParameter)objs[0], (Long)objs[1], (Long)objs[2]);
						break;
					case IODWON_MESSAGE:
						long time2 = System.currentTimeMillis();
						if((time2 - lastTime)< LIMIT_TIME){
							//may UI update too fast.
							return;
						}
						lastTime = time2;
						onDownBufferd((RequestParameter)objs[0], (Long)objs[1], (Long)objs[2]);
						break;
					default:
						break;
					}
				}
			};
		}
	}

	public abstract void onFinished(RequestParameter requestParameter, T response);
	public abstract void onCompleted(RequestParameter requestParameter);
	public abstract void onCanceled(RequestParameter requestParameter);
	public abstract void onFailed(RequestParameter requestParameter,Exception e);
	public abstract void onRetry(RequestParameter requestParameter,int count,Exception e);
	public abstract void onUpBufferd(RequestParameter requestParameter,long up,long total);
	public abstract void onDownBufferd(RequestParameter requestParameter,long down,long total);
	/**
	 * this method invoke on background thread.
	 * @param response
	 * @return
	 */
	public abstract T parser(String response) throws Exception;

	@Override
	public void upBufferd(RequestParameter requestParameter, long up, long total) {
		if(handler != null){
			Object[] objs = {requestParameter,up,total};
			handler.sendMessage(handler.obtainMessage(IOUP_MESSAGE, objs));
		}
	}

	@Override
	public void downBufferd(RequestParameter requestParameter, long down,
			long total) {
		if(handler != null){
			Object[] objs = {requestParameter,down,total};
			handler.sendMessage(handler.obtainMessage(IODWON_MESSAGE, objs));
		}
	}

	@Override
	public void finished(RequestParameter requestParameter, String response) {
		if(handler != null){
			try {
				Object[] objs = {requestParameter,parser(response)};
				handler.sendMessage(handler.obtainMessage(SUCCESS_MESSAGE, objs));
			} catch (Exception e) {
				failed(requestParameter, e);
			}
		}
	}

	@Override
	public void canceled(RequestParameter requestParameter) {
		if(handler != null){
			handler.sendMessage(handler.obtainMessage(CANCEL_MESSAGE, requestParameter));
		}
	}

	@Override
	public void failed(RequestParameter requestParameter, Exception e) {
		if(handler != null){
			Object[] objs = {requestParameter,e};
			handler.sendMessage(handler.obtainMessage(FAILURE_MESSAGE, objs));
		}
	}

	@Override
	public void retry(RequestParameter requestParameter, int count, Exception e) {
		if(handler != null){
			Object[] objs = {requestParameter,count,e};
			handler.sendMessage(handler.obtainMessage(RETRY_MESSAGE, objs));
		}
	}

}
